package org.fengzhi.server.alipay.controller;

import com.alipay.api.internal.util.AlipaySignature;
import org.apache.log4j.Logger;
import org.fengzhi.server.alipay.config.AlipayConfig;
import org.fengzhi.server.alipay.service.IAlipayService;
import org.fengzhi.server.alipay.util.AlipayNotify;
import org.fengzhi.server.alipay.util.OrderInfoUtil2_0;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Controller
@RequestMapping(value = "/pay", produces = "text/html;charset=utf-8")
public class AlipayNotifyController {

    public Logger log = Logger.getLogger(getClass().getName());

    @Autowired
    public IAlipayService alipayService;


    /**
     * 客户端获取签名后的订单信息：客户端只能获取签名后的信息，防止私密信息泄露。
     *
     * @param body
     * @param subject
     * @param outTradeNo
     * @param totalAmount
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "/getOrderInfo", method = RequestMethod.GET)
    public String getOrderInfo(String body, String subject, String outTradeNo, String totalAmount) throws Exception {
        // 请求参数拼接
        Map<String, String> publicData = OrderInfoUtil2_0.buildOrderParamMap(body, subject, outTradeNo, totalAmount);
        String orderParam = OrderInfoUtil2_0.buildOrderParam(publicData);
        // 对参数进行签名
        String sign = OrderInfoUtil2_0.getSign(publicData, AlipayConfig.private_key);
        final String orderInfo = orderParam + "&" + sign;

        return orderInfo;
    }

    /**
     * 被动接收支付宝通知：接收支付宝异步通知，验证信息并处理订单。
     *
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/verifySign", method = RequestMethod.POST)
    public void verifySign(HttpServletRequest request, HttpServletResponse response) throws Exception {
        PrintWriter out = response.getWriter();

        //获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            //  valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }

        //异步通知ID
        String notify_id = request.getParameter("notify_id");

        //判断接受的post通知中有无notify_id，如果有则是异步通知。
        if (notify_id != null && notify_id != "") {
            //判断成功之后使用getResponse方法判断是否是支付宝发来的异步通知。
            if (AlipayNotify.verifyResponse(notify_id).equals("false")) {

                // 调用sdk验证签名
                boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.input_charset);

                if (signVerified) {
                    log.info("验签成功！");

                    //商户订单号
                    String outTradeo = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
                    // 总金额
                    double totalAmount = new Double(new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8"));
                    // 商家id
                    String sellerId = new String(request.getParameter("seller_id").getBytes("ISO-8859-1"), "UTF-8");
                    // 应用id
                    String appId = new String(request.getParameter("app_id").getBytes("ISO-8859-1"), "UTF-8");

                    //验证业务内容是否正确
                    boolean businessVerified = alipayService.verifyBusinessData(outTradeo, totalAmount, sellerId, appId);

                    if (businessVerified) {
                        //交易状态
                        String tradeStatus = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");

                        if (tradeStatus.equals("TRADE_SUCCESS")) {
                            // 支付成功处理方式

                            // 更新商户系统中用户交易订单信息等等。。。

                            out.print("success");
                        } else {
                            // 支付失败处理方式
                            log.info("支付失败！");

                            out.print("failure");
                        }
                    } else {
                        out.print("failure");
                        log.info("交易信息不正确！");
                    }
                } else {
                    out.print("failure");
                    log.info("验证签名失败！");
                }
            } else {
                out.print("failure");
                log.info("验证是否来自支付宝的通知失败！");
            }
        } else {
            out.print("failure");
            log.info("接收通知错误！");
        }

    }
}
